home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Tool Chest / Dev.CD Feb 97 TC.toast / Sample Code / Games / MoofWars / MoofWars Sprocket 8⁄15⁄96 / •Source / TSpriteCollection.cp < prev    next >
Encoding:
Text File  |  1996-08-19  |  5.1 KB  |  185 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************
  2. #
  3. #    TSpriteCollection.cp
  4. #    
  5. #    This class represents a group of related Sprites.  For example, all of the shots
  6. #    fired by a sprite.  In general, the various things that happen to sprites (moving,
  7. #    drawing, hit testing) all happen to a whole group at a time.
  8. #
  9. #
  10. #    Author: Timothy Carroll
  11. #    Apple Developer Technical Support
  12. #    timc@apple.com
  13. #
  14. #    Modification History: 
  15. #
  16. #    8/15/96        TMC     Initial Release
  17. #
  18. #    Copyright © 1996 Apple Computer, Inc., All Rights Reserved
  19. #
  20. #
  21. #    You may incorporate this sample code into your applications without
  22. #    restriction, though the sample code has been provided "AS IS" and the
  23. #    responsibility for its operation is 100% yours.  However, what you are
  24. #    not permitted to do is to redistribute the source as "DSC Sample Code"
  25. #    after having made changes. If you're going to re-distribute the source,
  26. #    we require that you make it clear in the source that the code was
  27. #    descended from Apple Sample Code, but that you've made changes.
  28. #
  29. *************************************************************************************/
  30.  
  31.  
  32.  
  33. #include "TSpriteCollection.h"
  34.  
  35. TSpriteCollection::TSpriteCollection(void)
  36. {
  37.     fSpriteListHead = NULL;
  38. }
  39.  
  40. TSpriteCollection::~TSpriteCollection(void)
  41. {
  42.     TSprite *currentSprite, *nextSprite;
  43.  
  44.     nextSprite = fSpriteListHead;
  45.     
  46.     while (nextSprite != NULL)
  47.     {
  48.         currentSprite = nextSprite;
  49.         nextSprite = currentSprite->fNextSprite;
  50.         
  51.         // When we delete a group, we make all of the sprites invisible.  This kills a warning
  52.         // in the sprite code.
  53.         currentSprite->SetVisibility(kInvisible);
  54.         delete currentSprite;
  55.     }
  56.     
  57. }
  58.  
  59. void TSpriteCollection::AddSprite (TSprite *theSprite)
  60. {
  61.     if (fSpriteListHead == NULL)
  62.         fSpriteListHead = theSprite;
  63.     else
  64.     {    
  65.         theSprite->fNextSprite = fSpriteListHead;
  66.         fSpriteListHead->fPrevSprite = theSprite;
  67.         theSprite->fPrevSprite = NULL;
  68.         fSpriteListHead = theSprite;
  69.     }
  70. }
  71.  
  72. void TSpriteCollection::RemoveSprite (TSprite *theSprite)
  73. {    
  74.     TSprite *prevSprite, *nextSprite;
  75.     
  76.     prevSprite = theSprite->fPrevSprite;
  77.     nextSprite = theSprite->fNextSprite;
  78.     
  79.     if (prevSprite == NULL)
  80.         fSpriteListHead = nextSprite;
  81.     else
  82.         prevSprite->fNextSprite = nextSprite;
  83.         
  84.     if (nextSprite != NULL)
  85.         nextSprite->fPrevSprite=prevSprite;
  86. }
  87.  
  88. void TSpriteCollection::ProcessSpriteGroup (void)
  89. {
  90.     TSprite *currentSprite, *nextSprite;
  91.  
  92.     nextSprite = fSpriteListHead;
  93.     
  94.     // Just a comment about the structure of these loops.  We get the next
  95.     // sprite before we call process sprite because process sprite can delete
  96.     // the sprite which would throw our iterator off completely.
  97.     
  98.     // We're using the same structure in all of the other loops as well. However,
  99.     // any routine that is disallowed from destroying a sprite (for example, 
  100.     // drawing and erasing should probably never actually destroy a sprite), then
  101.     // we can use a simpler structure:
  102.     
  103.     /*
  104.     currentSprite = fSpriteListHead;
  105.     while (currentSprite != NULL)
  106.     {
  107.         currentSprite->foo();
  108.         currentSprite = currentSprite->fNextSprite;
  109.     }
  110.     */
  111.     while (nextSprite != NULL)
  112.     {
  113.         currentSprite = nextSprite;
  114.         nextSprite = currentSprite->fNextSprite;
  115.         currentSprite->ProcessSprite();
  116.     }
  117. }
  118.  
  119.  
  120. // HitTest routine currently uses some of the inner knowledge of how TSprite works.
  121. // So if TSprite is modified, this routine may need to be altered.  This is an ugly
  122. // routine, and I only do it here to cache some information.  I need to test and see
  123. // if these optimizations are doing anything.
  124.  
  125. void TSpriteCollection::HitTest (TSpriteCollection *targetGroup)
  126. {
  127.     TSprite *currentTarget, *nextTarget, *currentSprite, *nextSprite;
  128.     TGraphic *targetGraphic, *spriteGraphic;
  129.     SInt32 targV, targH, spriteV, spriteH;
  130.     
  131.     nextTarget = targetGroup->fSpriteListHead;
  132.     nextSprite = this->fSpriteListHead;
  133.     
  134.     // quick short circuit
  135.     if (nextTarget == NULL || nextSprite == NULL)
  136.         return;
  137.     
  138.     while (nextTarget != NULL)
  139.     {
  140.         currentTarget = nextTarget;
  141.         nextTarget = currentTarget->fNextSprite;
  142.  
  143.         if (currentTarget->GetVisibility () == kInvisible)
  144.             continue;
  145.             
  146.         targH = (currentTarget->fCoordX >> 16) - currentTarget->fXOffset;
  147.         targV = (currentTarget->fCoordY >> 16) - currentTarget->fYOffset;
  148.         targetGraphic = currentTarget->fSpriteImages->GetTGraphic(currentTarget->fFace);
  149.         
  150.         nextSprite = this->fSpriteListHead;
  151.         while (nextSprite != NULL)
  152.         {
  153.             currentSprite = nextSprite;
  154.             nextSprite = currentSprite->fNextSprite;
  155.  
  156.             if (currentSprite->GetVisibility () == kInvisible)
  157.                 continue;
  158.             
  159.             spriteH = (currentSprite->fCoordX >> 16) - currentSprite->fXOffset;
  160.             spriteV = (currentSprite->fCoordY >> 16) - currentSprite->fYOffset;
  161.             spriteGraphic = currentSprite->fSpriteImages->GetTGraphic(currentSprite->fFace);
  162.             
  163.             if (TGraphic::Intersect (targetGraphic, spriteGraphic, targV,targH,spriteV,spriteH))
  164.             {
  165.                 currentTarget->Collision(currentSprite);
  166.                 currentSprite->Collision(currentTarget);
  167.             }
  168.         }
  169.     }
  170. }    
  171.  
  172. void TSpriteCollection::DrawSpriteGroup (void)
  173. {
  174.     TSprite *currentSprite, *nextSprite;
  175.  
  176.     nextSprite = fSpriteListHead;
  177.     
  178.     while (nextSprite != NULL)
  179.     {
  180.         currentSprite = nextSprite;
  181.         nextSprite = currentSprite->fNextSprite;
  182.         currentSprite->DrawSprite();
  183.     }
  184.  
  185. }